/**
 * 判断是否为整数
 * @param {number} value
 * @returns {boolean}
 */
export const isInteger = (value: number): boolean => (value | 0) === value
// export const isInteger = (value: number): boolean => Number.isInteger(number)

/**
 * 数组随机排序
 * @param {Array} arr
 * @returns {Array}
 */
export const shuffle = <T>(arr: T[]): T[] =>
  arr.sort(() => 0.5 - Math.random()).sort(() => 0.5 - Math.random())

/**
 * 数组随机排序 => 洗牌算法
 * @param {Array} arr
 * @returns {Array}
 */
export function shuffleNew<T>(arr: T[]): T[] {
  for (let i = arr.length - 1; i > 0; i--) {
    const randomIndex = Math.floor(Math.random() * (i + 1))
    ;[arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]]
  }
  return arr
}

/**
 * 随机获取一个布尔值
 * @returns {boolean}
 */
export const randomBool = (): boolean => Math.random() < 0.5

/**
 * 把数组最后一项移动到第一项
 * @param {Array} arr
 * @returns
 */
export function firstToLast<T>(arr: T[]): T[] {
  arr.unshift(arr.pop() as T)
  return arr
}

/**
 * 把数组第一项移动到最后一项
 * @param {Array} arr
 * @returns
 */
export function lastToFirst<T>(arr: T[]): T[] {
  arr.push(arr.shift() as T)
  return arr
}

/**
 * 简单数据类型数组去重
 * @param {Array} arr
 * @returns
 */
export const uniqueArr = <T>(arr: T[]): T[] => [...new Set(arr)]

/**
 * 复杂数据类型数组去重
 * @param {Array} arr
 * @returns
 */
export const intricateArr = <T>(arr: T[], key: string): T[] => {
  const obj: { [k: string]: boolean } = {}
  const newArr: T[] = []
  arr.forEach((item) => {
    if (!obj[(item as { [k: string]: string })[key]]) {
      obj[(item as { [k: string]: string })[key]] = true
      newArr.push(item)
    }
  })
  return newArr
}

/**
 * 随机获取颜色
 * @returns {string}
 */
export const getRendomColor = (): string =>
  `#${Math.floor(Math.random() * 0xffffff).toString(0x00)}`

/**
 * 是否为空对象
 * @param {object} obj
 * @returns
 */
export const isEmpty = (obj: {
  [k: string | symbol]: string | boolean | number | symbol | unknown
}): boolean =>
  // Object.keys(obj).length === 0 && obj.constructor === Object
  Reflect.ownKeys(obj).length === 0 && obj.constructor === Object

/**
 * 比较时间
 * @param {Date} a
 * @param {Date} b
 * @returns {boolean}
 */
export const compare = (a: Date, b: Date): boolean => a.getTime() > b.getTime()

/**
 * 从时间中提取年月日时分秒
 * @param {Date} date 当前时间
 * @param {number} num 时区 => 默认 8
 * @returns {string[]} 时间数组
 */
export function extract(date: Date, num = 8): string[] {
  const d = new Date(new Date(date).getTime() + num * 3600 * 1000)
  return new Date(d)
    .toISOString()
    .split(/[^0-9]/)
    .slice(0, -1)
}

/**
 * 参数求和
 * @param {number[]} args 参数集
 * @returns {number} 参数相加的值
 */
export const sum = (...args: number[]): number =>
  args.reduce((a: number, b: number) => a + b)

/**
 * 深度冻结对象
 * @param obj
 */
export const constTize = (
  obj: Record<string | symbol, unknown>
): Record<string | symbol, unknown> => {
  if (Object.isFrozen(obj)) {
    return obj
  }
  Object.keys(obj).forEach((key) => {
    if (typeof obj[key] === 'object') {
      obj[key] = constTize(obj[key] as Record<string | symbol, unknown>)
    }
  })
  return Object.freeze(obj)
}
